import React, { useEffect } from "react";
import { Form, Input, Button, Checkbox, message } from "antd";
import { UserOutlined, LockOutlined } from "@ant-design/icons";
import { useNavigate } from "react-router-dom";

import "./login.less";
// 可以直接导入图片在代码中用{logo}来使用
import logo from "./images/favicon.png";
import { reqLogin } from "../../api";
import memoryUtils from "../../utils/memoryUtils";
import storage from "../../utils/storageUtils";
import { setHeadTitle } from "../../redux/action";
import { connect } from "react-redux";
import { login } from "../../redux/action";
// 登录路由组件
const Login: React.FC = (props: any) => {
  const [form] = Form.useForm();
  // react-router-domV6 版本后用useNavigate狗子代替了useHistory
  let history = useNavigate();

  //页面会加载一次memoryUtils.user中的用户信息,每次user变化都会触发useEffect
  // 如果userinfo有信息说明已经登陆过并且写入到localStorage中了,就不会停留在login界面了直接跳转到admin
  // 除非自己手动删除在localstorage中的user用户信息
  // const userid = memoryUtils.user._id;
  // 直接从redux中读取user信息
  const userid = props.user._id;
  const errorMsg = props.user.errorMsg;
  // console.log(userid);
  useEffect(() => {
    // 如果localsrorage中已经有用户信息就跳转admin页面
    if (userid) {
      console.log(userid);
      history("/admin", { replace: true });
    }

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userid]);

  // 自定义事件 点击提交会执行
  const onFinish = async (values: any) => {
    // 点击登录之后绑定的事件
    // console.log("Received values of form: ", values);
    // 只有通过给到rules验证种植 才会执行下面的代码 否则只会提示rules的message

    // 输入都符合要求之后才会执行下面的代码
    // console.log("输入都符合要求之后我才会输出！");

    // 结构出用户的输入

    // 用redux来代替下面的所有方法
    const { username, password } = values;

    // 原生promise写法写的内容比较多
    // reqLogin(username, password)
    //   ?.then((response) => console.log(response.data))
    //   .catch((err) => console.log("something wrong"));

    // 使用async和await没有.catch所以需要包含在try catch中
    try {
      // 需要对reqLogin函数的返回值做接口设置 否则会找不到response上的属性
      const response = await reqLogin(username, password);
      // console.log(response);

      // response是所有返回信息，其中data是我们需要的内容
      const result = response.data;
      if (result.status === 0) {
        // 登陆成功
        message.success("登录成功！");
        // 登录成功后保存用户信息在内存中
        const userInfo = result.data;
        // memoryUtils是存在内存中  刷新就会充值
        memoryUtils.user = userInfo;
        // storage是存在localStorage中 有持久性
        storage.saveUser(userInfo);
        //登录成功后跳转页面到admin
        //使用的是最新的react-router-dom的页面跳转方法,代替原来的编程式导航种的replace
        history("/admin", { replace: true });
        // 每次重新登陆i的时候都重新把redux中的title信息给修改为首页
        // 这样每次登录上去就不会显示上次退出登陆时候的遗留title信息
        props.setHeadTitle("首页");
      } else {
        // 登陆失败 失败的时候data中会有msg,里面说明失败的原因
        message.error(result.msg);
      }
    } catch (error) {
      console.log("请求出错了！");
    }
  };

  return (
    // 全部内容都在login中
    <div className="login">
      {/* header部分 有名字和图标部分 */}
      <header className="login-header">
        <div className="background"></div>
        <img className="logo" src={logo} alt="logo" />
        <h1>
          基于React管理平台
          <span> - Made by ShenZY98</span>
        </h1>
      </header>

      {/* login-content为登录表单部分 */}
      <section className="login-content">
        <div>{errorMsg}</div>
        <h2>登录</h2>
        <Form
          form={form}
          name="normal_login"
          className="login-form"
          initialValues={{ remember: true }}
          // 点击登录出发事件onfinish
          onFinish={onFinish}
        >
          <Form.Item
            name="username"
            className="site-form-item-info"
            rules={[
              // 对于输入用户名的校验  这种叫做声明式验证  直接使用的是别人已经设计好的验证方式
              { required: true, whitespace: true, message: "请输入用户名！" },
              { min: 4, message: "用户名最短不能小于4位！" },
              { max: 12, message: "用户名最长不能大于12位！" },
              // 正则验证用户名内容
              {
                pattern: /^[a-zA-Z0-9_]+$/,
                message: "用户名必须是英文数字和下划线！",
              },
            ]}
          >
            <Input
              className="site-form-item-input"
              prefix={<UserOutlined className="site-form-item-icon" />}
              placeholder="请输入用户名"
            />
          </Form.Item>
          <Form.Item
            className="site-form-item-info"
            name="password"
            rules={[{ required: true, message: "请输入密码！" }]}
          >
            <Input
              className="site-form-item-input"
              prefix={<LockOutlined className="site-form-item-icon" />}
              type="password"
              placeholder="请输入密码"
            />
          </Form.Item>
          <Form.Item>
            <Form.Item name="remember" valuePropName="checked" noStyle>
              <Checkbox className="remeber-checkbox">Remember me</Checkbox>
            </Form.Item>
          </Form.Item>

          <Form.Item>
            <Button
              type="primary"
              htmlType="submit"
              className="login-form-button"
            >
              登录
            </Button>
          </Form.Item>
        </Form>
      </section>

      {/* 页面底部footer 纯装饰用的 */}
      <footer className="login-footer"></footer>
    </div>
  );
};

// 把store中的dispatch映射为一般方法
const mapDispatchToProps = (dispatch: any) => {
  return {
    setHeadTitle: (title: any) => {
      dispatch(setHeadTitle(title));
    },
    login: (username: any, password: any) => {
      dispatch(login(username, password));
    },
  };
};

// react-redux的connect把ui组件和状态连接起来
export default connect(
  // 因为left-bav组件不涉及状态的显示  所以这里只需要一mapDispatchToProps即可 下面对应mapStateToProps中并没有转换任何的redux中的状态
  (state: any) => ({ user: state.user }),
  //mapDispatchToProps 把store中的dispatch映射为一般方法传给组件的props 组件中可以直调用props.setHeadTitle()
  mapDispatchToProps
)(Login);
// export default Login;
